﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;


namespace HarryPotter
{
    class BasketPermutation
    {
        private const double PricePerBook = 8.0;

        private readonly int[] _orgBasket;

        private int[] _serie; 
        private BasketPermutation _remainingBasket;
        private long _permutationGenerator;

        public BasketPermutation( int[] basket )
        {
            _orgBasket = basket;
            _permutationGenerator = 0;
        }

        public BasketPermutation CreateNext()
        {
            _permutationGenerator++;

            while (!IsValidPermutation(_permutationGenerator) )
            {
                _permutationGenerator++;
            }

            int[] remainingBasket = _orgBasket;
            
            long perm = _permutationGenerator;
            while ( perm > 0 )
            {
                if ( perm % 2 == )
                {
                    remainingBasket[idx]--;
                    _serie[idx] = 1;
                }
                perm >>= 1;
            }
        
            _remainingBasket = new BasketPermutation( remainingBasket );
            return _remainingBasket;
        }

        static private bool IsValidPermutation( long perm )
        {
            int bitCount = 0;
            while ( perm > 0 )
            {
                if (perm % 2 == 1)
                    bitCount++;
                perm >>= 1;                
            }

            if (bitCount > 1 && bitCount < 6 )
                return true;
            return false;
        }

        public double CalculatePrice()
        {
            int totalBookCount = 0;
            int discountableBookCount = 0;

          
            foreach (int bookCount in _orgBasket)
            {
                totalBookCount += bookCount;
                if (bookCount > 0 && discountableBookCount < 5)
                {
                    discountableBookCount++;
                }
            }

            double discount = 1.0;

            switch (discountableBookCount)
            {
                case 0:
                case 1:
                    discount = 1.0;
                    break;

                case 2:
                    discount = 0.95;
                    break;

                case 3:
                    discount = 0.9;
                    break;

                case 4:
                    discount = 0.8;
                    break;

                case 5:
                    discount = 0.75;
                    break;

                default:
                    Debug.Assert(false);
                    return -9999.0;
            }
 

            return PricePerBook*(totalBookCount - discountableBookCount) + PricePerBook*discount*discountableBookCount;
        }
        
    }
}
